package com.zrf.gulimall.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zrf.gulimall.common.database.utils.PageUtils;
import com.zrf.gulimall.common.database.utils.Query;
import com.zrf.gulimall.product.dao.AttrGroupDao;
import com.zrf.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.zrf.gulimall.product.entity.AttrEntity;
import com.zrf.gulimall.product.entity.AttrGroupEntity;
import com.zrf.gulimall.product.service.AttrAttrGroupRelationService;
import com.zrf.gulimall.product.service.AttrGroupService;
import com.zrf.gulimall.product.service.AttrService;
import com.zrf.gulimall.product.vo.AttrGroupVo;
import com.zrf.gulimall.product.vo.web.SpuItemAttrGroupVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

	@Resource
	private AttrAttrGroupRelationService attrAttrGroupRelationService;

	@Resource
	private AttrService attrService;

	@Resource
	private AttrGroupDao attrGroupDao;

	@Override
	public PageUtils queryPage(Map<String, Object> params, Long catalogId) {
		String key = (String) params.get("key");
		IPage<AttrGroupEntity> page = this.lambdaQuery()
				.eq(!catalogId.equals(0L), AttrGroupEntity::getCatelogId, catalogId)
				.and(StrUtil.isNotEmpty(key), item -> item.eq(AttrGroupEntity::getAttrGroupId, key).or().like(AttrGroupEntity::getAttrGroupName, key))
				.page(new Query<AttrGroupEntity>().getPage(params));
		return new PageUtils(page);
	}

	@Override
	public List<AttrGroupEntity> queryByCatalogId(Long catalogId) {
		return this.lambdaQuery()
				.eq(Objects.nonNull(catalogId), AttrGroupEntity::getCatelogId, catalogId)
				.list();
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void delete(List<Long> attrGroupIds) {
		attrAttrGroupRelationService.remove(
				Wrappers.<AttrAttrgroupRelationEntity>lambdaQuery()
						.in(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupIds)
		);
		this.removeByIds(attrGroupIds);
	}

	@Override
	public List<AttrGroupVo> queryWithAttrs(Long catalogId) {
		// 查询分类下的所有分组
		List<AttrGroupEntity> groupEntities = this.lambdaQuery().eq(Objects.nonNull(catalogId), AttrGroupEntity::getCatelogId, catalogId).list();
		List<Long> attrGroupIdList = groupEntities.stream().map(AttrGroupEntity::getAttrGroupId).collect(Collectors.toList());
		if (CollUtil.isEmpty(attrGroupIdList)) {
			return null;
		}
		// 根据分组id查询关联的属性
		List<AttrAttrgroupRelationEntity> relationEntities = attrAttrGroupRelationService.queryByAttrGroupIds(attrGroupIdList);
		List<Long> attrIdList = relationEntities.stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());
		List<AttrEntity> attrEntities = attrService.listByIds(attrIdList);
		// 将属性以id为key，转为map
		Map<Long, AttrEntity> attrMap = attrEntities.stream().collect(Collectors.toMap(AttrEntity::getAttrId, Function.identity()));
		// 将关联对象按分组id分组，value映射为对应的分组下的属性
		Map<Long, List<AttrEntity>> attrGroupMap = relationEntities.stream()
				.collect(Collectors.groupingBy(AttrAttrgroupRelationEntity::getAttrGroupId, Collectors.mapping(
						item -> attrMap.get(item.getAttrId()), Collectors.toList()
				)));
		// 转为vo返回
		return groupEntities.stream().map(item -> {
			AttrGroupVo attrGroupVo = new AttrGroupVo();
			BeanUtil.copyProperties(item, attrGroupVo);
			attrGroupVo.setAttrs(attrGroupMap.get(item.getAttrGroupId()));
			return attrGroupVo;
		}).collect(Collectors.toList());
	}

	@Override
	public List<SpuItemAttrGroupVo> getAttrGroupWithAttrsBySpuId(Long spuId, Long catalogId) {
		List<SpuItemAttrGroupVo> vos = attrGroupDao.getAttrGroupWithAttrsBySpuId(spuId, catalogId);
		return vos;
	}

}